import { Component, OnInit, AfterViewInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpService } from '@kylin/http';
declare var AMap: any;
declare var Loca: any;
declare var area: any;
import * as _ from 'lodash';
@Component({
  templateUrl: './statistical-map.component.html',
  styleUrls: ['./statistical-map.component.less']
})
export class StatisticalMapComponent implements OnInit, AfterViewInit {
  private colors = ['#1a9850', '#91cf60', '#d9ef8b', '#fee08b', '#fc8d59', '#d73027'];
  amap: any;
  current = 0;
  radioValue: any;
  validateForm: FormGroup;
  selectPropertiesMultiple = 'default';
  seletcPropertiesMaxMultipleCount = 1;
  submitButtonLoading = false;
  templateNotes = {
    A: '分段设色仅支持单属性展示',
    B: '柱状统计仅支持单属性展示',
    C: '饼状统计支持全选,但选择过多的属性会导致展示效果较差',
    D: '文字统计只支持单属性展示'
  }
  currentNotes = this.templateNotes.A;
  private translator = {
    template: '请选择统计模板',
    layers: '请选择图层',
    properties: '请选择图层属性'
  }
  layersOnSearchController = null;
  layersOptions = null;
  propertiesOptions = null;

  private statisticalData = null;
  private statisticalPropertiesany = null;
  constructor(
    private nzMessageService: NzMessageService,
    private fb: FormBuilder,
    private http: HttpService
  ) { }

  ngOnInit() {
    this.validateFormInit();
    this.fetchLayersOptions('');
  }

  ngAfterViewInit() {

  }

  next(res?): void {
    if (res) {
      let dataAvailability = true;
      _.forIn(res.data.list[0], (value, key) => {
        if (key !== 'the_geom' && key !== 'color' && key !== 'lnglat') {
          if (_.isNaN(+value)) {
            if (this.fetchStatisticsTemplate() !== 'D') {
              dataAvailability = false;
              this.nzMessageService.warning(`属性${key}不是数值,无法用于分段设色,柱状统计`);
            }
          }
        }
      });
      if (!dataAvailability) {
        return;
      }
    }
    this.statisticalData = this.formattingStatistics(res.data);
    this.current = 1;
    setTimeout(() => {
      this.aMapInit();
    }, 0)
  }
  back() {
    this.current = 0;
  }

  private checkForm(controls): boolean {
    let hasError = false;
    _.forIn(controls, (value, key) => {
      if (value.errors) {
        this.nzMessageService.error(this.translator[key]);
        hasError = true;
      }
    })
    return hasError;
  }

  templateChange($event) {
    if ($event) {
      this.currentNotes = this.templateNotes[$event];
      switch ($event) {
        case 'B':
          this.selectPropertiesMultiple = 'default';
          this.seletcPropertiesMaxMultipleCount = 1;
          break;
        case 'C':
          this.selectPropertiesMultiple = 'multiple';
          this.seletcPropertiesMaxMultipleCount = Infinity;
          break;
        case 'D':
          this.seletcPropertiesMaxMultipleCount = 1;
          this.selectPropertiesMultiple = 'default';
          break;
        default: // 当时A的情况下,因为重置表单的时候会让数值为空,然后我们会重置template默认选择为A
          this.seletcPropertiesMaxMultipleCount = 1;
          this.selectPropertiesMultiple = 'default';
      }
    }
  }

  private validateFormInit() {
    this.validateForm = this.fb.group({
      template: ['A', [Validators.required]],
      layers: [null, [Validators.required]],
      properties: [null, [Validators.required]]
    });
  }

  resetForm() {
    this.validateForm.reset();
    this.validateForm.get('template').setValue('A');
  }

  fetchLayersOptions($event) {
    clearTimeout(this.layersOnSearchController);
    this.layersOnSearchController = setTimeout(() => {
      this.http.get('http://192.168.1.100:8091/layer/mapCount', { layerName: $event })
        .then(res => {
          if (res.resp_code === '10000') {
            if (_.isEmpty(res.data.layerList)) {
              this.nzMessageService.warning('未搜索到相关图层,换一个搜索词试试?');
            } else {
              this.layersOptions = res.data.layerList.map(e => {
                return { label: e.layerName, value: e.layerId }
              })
            }
          }
        })
        .catch(err => {

        })
    }, 300)
  }

  fetchPropertiesOptions($event) {
    if ($event) {
      this.validateForm.get('properties').setValue(null);
      this.http.get('http://192.168.1.100:8091/layer/mapCount', { layerId: $event })
        .then(res => {
          if (res.resp_code === '10000') {
            this.propertiesOptions = _.compact(res.data.propertyList.map(e => {
              if (e !== 'the_geom') { // 此属性是经纬度,后端会自动带上,所以不需要选择此属性
                return { label: e, value: e };
              }
            }));
          }
        })
        .catch(err => {

        })
    }
  }

  submitForm(): void {
    this.submitButtonLoading = true;
    const hasError = this.checkForm(this.validateForm.controls);
    if (hasError) {
      this.submitButtonLoading = false;
      return;
    }
    const params = this.validateForm.value;
    this.http.post('http://192.168.1.100:8091/layer/countResult', {}, { layerId: params.layers, propertyList: params.properties.toString(), size: '20' })
      .then(res => {
        if (res.resp_code === '10000') {
          this.statisticalData = null;
          this.amap = null;
          this.statisticalPropertiesany = null;
          // todo 数据有7种格式需要处理
          this.next(res);
        } else {
          this.nzMessageService.warning(res.resp_msg);
        }
        this.submitButtonLoading = false;
      })
      .catch(err => {
        this.submitButtonLoading = false;
        this.nzMessageService.warning('查询失败!');
      })
  }

  private formattingStatistics(res: any) { // todo  点图层没办法用于分段设色
    const layerType = res.layerType;
    const type = res.type;
    const data = res.list.map((e, index) => {
      e.color = this.colors[index % this.colors.length];
      return e;
    });
    this.statisticalPropertiesany = [];
    _.forIn(_.cloneDeep(data[0]), (value, key) => {
      if (key !== 'the_geom') {
        this.statisticalPropertiesany.push(key);
      }
    });

    switch (type) {
      case 'MULTIPOLYGON':
        return this.handlerMultiPolygon(data);
      case 'MULTILINESTRING':
        return this.handlerMultiLineString(data);
      case 'POINT':
        return this.handlerPoint(data);
      default: // POINT
        this.nzMessageService.success('formattingStatistics使用了default,可能的结果是出现了新的数据类型');
        console.log(res);
        return this.handlerPoint(data);
    }

  }

  private handlerMultiLineString(data) {
    return data.map(e => {
      e.lnglat = e.the_geom.split(',').map(v => {
        return v.split(' ');
      });
      delete e.the_geom;
      return e;
    })

  }

  private handlerPoint(data) {
 
    return data.map(e => {
      e.lnglat = e.the_geom.split(' ');
      delete e.the_geom;
      return e;
    })
  }

  private handlerMultiPolygon(data) {
    const result = [];
    data.map(e => {
      const clone = _.cloneDeep(e.the_geom);
      delete e.the_geom;
      const arr = this.filterString(clone);
      arr.map(value => {
        const lnglat = { lnglat: value };
        result.push({ ...lnglat, ...e });
      })
    })
    return result;
  }

  private filterString(data: any) {
    const type = this.strtingType(data); // todo 该处理那些复杂嵌套数据
    if (type === 2) {
      data = data + ',';
      data = data.split(')),');
      data.pop();
      return data.map((e) => {
        const arr = e.substring(2).split(',');
        return arr.map((v) => {
          return v.split(' ');
        })
      });
    }
  }

  private strtingType(str: string) {
    if (str.indexOf('((') !== -1) {
      return 2;
    } else if (str.indexOf('(') !== -1) {
      return 1;
    } else {
      return 0;
    }
  }

  private aMapInit() {
    let mapStyle = 'amap://styles/twilight';
    if (this.fetchStatisticsTemplate() === 'D') {
      mapStyle = 'amap://styles/midnight';
    }
    this.amap = new AMap.Map('amap', {
      mapStyle: mapStyle,
      viewMode: '3D',
      features: ['bg', 'road'],
      pitch: 50,
      zoom: 9,
      center: [108.909572, 34.310249],
      zooms: [5, 11]
    });
    this.createMapLayer();
  }

  private fetchStatisticsTemplate() {
    return this.validateForm.get('template').value;
  }

  private createMapLayer() {
    const statisticsTemplate = this.fetchStatisticsTemplate();
    switch (statisticsTemplate) {
      case 'A':
        this.segmentedColor();
        break;
      case 'B':
        this.columnarStatistics();
        break;
      case 'C':
        this.pieStatistics();
        break;
      case 'D':
        this.textStatistics();
        break;
    }
  }

  private segmentedColor() {  // A
    const colors = ['#c6dbef', '#9ecae1', '#6baed6', '#3182bd', '#08519c'];

    const layer = new Loca.PolygonLayer({
      map: this.amap,
      fitView: true
    });

    layer.setData(this.statisticalData, {
      lnglat: 'lnglat'
    });

    layer.setOptions({
      style: {
        opacity: 0.5,
        color: (res) => {
          const index = res.index;
          return colors[index % colors.length];
        },
        height: (v) => {
          let height = +v.value[this.statisticalPropertiesany[0]];
          if (height < 10) {
            height = height * 1000;
          } else if (height < 100) {
            height = height * 100;
          } else if (height < 1000) {
            height = height * 10
          }
          return height;
        }
      }
    });
    layer.render();
  }

  private columnarStatistics() { // B

    const layer = new Loca.GridLayer({
      map: this.amap,
      fitView: true
    });

    layer.setData(this.statisticalData, {
      lnglat: (obj) => {
        if (_.isArray(obj.value.lnglat[0])) {
          const val = obj.value;
          let lng = 0;
          let lat = 0;
          val.lnglat.map(value => {
            lng += +value[0];
            lat += +value[1];
          })
          const averageLng = lng / val.lnglat.length;
          const averageLat = lat / val.lnglat.length;
          return [averageLng, averageLat];
        } else {
          return obj.value.lnglat;
        }
      },
      value: this.statisticalPropertiesany[0]
    });
    // todo 这里目前高度有BUG 需要修复一下
    layer.setOptions({
      unit: 'meter',
      style: {
        color: ['#ecda9a', '#efc47e', '#f3ad6a', '#f7945d', '#f97b57', '#f66356', '#ee4d5a'],
        radius: 1500,
        opacity: 0.9,
        gap: 150,
        height: 10000
      }
    });
    layer.render();

  }

  private pieStatistics() {  // C

    // 参考百度sugar  https://sugar.baidubce.com/dashboard/41510e632e1e1e4767b0a041030670ec

  }

  private textStatistics() {  // D

    const layer = new Loca.LabelsLayer({
      fitView: true,
      map: this.amap
    });

    layer.setData(this.statisticalData, {
      lnglat: (obj) => {
        if (_.isArray(obj.value.lnglat[0])) {
          const val = obj.value;
          let lng = 0;
          let lat = 0;
          val.lnglat.map(value => {
            lng += +value[0];
            lat += +value[1];
          })
          const averageLng = lng / val.lnglat.length;
          const averageLat = lat / val.lnglat.length;
          return [averageLng, averageLat];
        } else {
          return obj.value.lnglat;
        }
      },
    })
    layer.setOptions({
      style: {
        direction: 'center',
        offset: [0, 0],
        text: (data) => {
          return this.statisticalPropertiesany[0] + data.value[this.statisticalPropertiesany[0]];
        },
        fillColor: (data) => {
          return data.value.color;
        },
        fontSize: (data) => {
          return 26;
        },
        strokeWidth: 0
      }
    }).render();
    layer.setzIndex(100);
  }


}
